package colony.ant;

import java.beans.DesignMode;
import java.util.List;

import colony.Agrupamento;
import colony.Colony;
import colony.DistanceMatrix;
import colony.Engine;
import colony.Grid;
import colony.Item;
import colony.Position;

public class Ant {

	private int failure;

	private int id;

	private Position position;

	private Grid grid;

	private List<Item> items;

	private Item currentItem;

	public Ant(Grid grid2, int i, List<Item> items2, Item current) {
		this.grid = grid2;
		this.id = i;
		this.items = items2;
		this.currentItem = current;
		this.position = this.currentItem.getPosition().clone();
		this.grid.remove(this.position);
	}

	public void setPosition(Position position) {
		this.position = position.clone();
	}

	public Position getPosition() {
		return position;
	}

	private double getPickProbability(double density) {

		/*
		 * if(density >= Engine.penalty){ return 1; }else{ return density; }
		 */
		// double aux = density
		// / (Math.pow(2 * Engine.neighborhoodSize + 1, 2) * Engine.penalty);
		double aux = density;
		if (aux >= 0.7)
			return 1;
		else
			return aux;
		// return density;

		// return Math.pow(Engine.kpick / (Engine.kpick + density), 2);
	}

	private double getDropProbability(double density) {
		/*
		 * if(density >= Engine.penalty){ return 0; }else{ return density; }
		 */

		// double aux = density
		// / (Math.pow(2 * Engine.nethis.speedighborhoodSize + 1, 2) *
		// Engine.penalty);
		// return 1
		// - density
		// / (Math.pow(2 * Engine.neighborhoodSize + 1, 2) * Engine.penalty);

		return 1 - density;

		// return density;
		// double aux = density / (Engine.kdrop + density);
		// return Math.pow(aux, 2);
	}

	public boolean pick() {
		if (!grid.isFree(this.position)) {
			double density = grid.getDstanceAt(this.id, this.position);
			double probability = getPickProbability(density);
			// if (Engine.rand.nextInt(1+(int) DistanceMatrix.total) <=
			// probability) {
			if (Engine.rand.nextDouble() < probability) {
				Item item = grid.getItemAt(this.position);
				item.setPicked(true);

				this.currentItem = item;
				grid.remove(this.position);
				return true;
			}
		}
		return false;
	}

	public boolean drop() {

		double density = grid.getDstanceAt(this.id, this.position);
		double drop = getDropProbability(density);

		// if (failure == 100 || Engine.rand.nextInt(1+(int)
		// DistanceMatrix.total) >= drop) {
		if (failure == 100 || Engine.rand.nextDouble() < drop) {
			if (failure == 100) {
				failure = 0;
			}

			innerDrop();
			return true;
		}
		failure++;
		return false;
	}

	public void innerDrop() {
//		System.out.print("id: " + this.currentItem.getId() + " antes: "
//				+ currentItem.getPosition().x + ", "
//				+ currentItem.getPosition().y + "\t");
		if (grid.isFree(this.position)) {
			grid.setItem(this.position, this.currentItem);
			this.currentItem.setPicked(false);
			this.currentItem.setPosition(this.position.x, this.position.y);
			grid.remove(this.position);
			Colony.updateMemory(this.currentItem.getPosition(),
					this.currentItem);
			grid.setFreeItem(this.currentItem);
			this.currentItem = null;
		} else {
			Position pos = grid.nexFree(this.position, this.position);
			this.position = pos.clone();
			grid.setItem(pos, this.currentItem);
			this.currentItem.setPicked(false);
			this.currentItem.setPosition(this.position.x, this.position.y);
			grid.remove(this.position);
			Colony.updateMemory(this.currentItem.getPosition(),
					this.currentItem);
			grid.setFreeItem(this.currentItem);
			this.currentItem = null;
		}
//		System.out.println("to: " + this.position.x + ", " + this.position.y);
	}

	public Item getCurrentItem() {
		return currentItem;
	}

	public void setCurrentItem(Item currentItem) {
		this.currentItem = currentItem;
	}

	public boolean step() {
		int oldx = this.position.x;
		int oldy = this.position.y;

		if (this.currentItem == null) {
			this.position = grid.moveAnt(this.position);
		} else {
			Position p = Colony.getBestMemory(this.currentItem);
			if (p != null) {
				this.position = grid.nexFree(this.position, p);
			} else {
				this.position = grid.nextRandom(this.position,
						this.currentItem.getId());

				Agrupamento.update(this.currentItem.getId(),
						Agrupamento.getNewClass());

				innerDrop();
				return true;
				// this.position =
				// grid.BestPosition(this.currentItem.getId(),this.position);
			}
		}
		return false;
		// System.out.println("from: ("+oldx+", "+oldy+")\t to: ("+this.position.x+", "+this.position.y+")");
	}

	public void finish() {
		if (this.currentItem == null) {
			return;
		}
		innerDrop();
	}
}
